package top.vanchor.myblog2back.controller.admin;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import top.vanchor.myblog2back.config.JwtConfigProperties;
import top.vanchor.myblog2back.entity.BackAdmin;
import top.vanchor.myblog2back.entity.BackAuthGroup;
import top.vanchor.myblog2back.entity.BackAuthGroupRule;
import top.vanchor.myblog2back.entity.BackAuthRule;
import top.vanchor.myblog2back.service.IBackAdminService;
import top.vanchor.myblog2back.service.IBackAuthGroupRuleService;
import top.vanchor.myblog2back.service.IBackAuthGroupService;
import top.vanchor.myblog2back.service.IBackAuthRuleService;
import top.vanchor.myblog2back.utils.JWTUtils;
import top.vanchor.myblog2back.utils.JwtInterceptor;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Ding
 * @create 2022/1/27 12:30
 */
@Api("后台管理员控制器")
@RestController
@CrossOrigin
@RequestMapping("/admin/adminUser")
public class AdminUserController {

    @Resource
    private IBackAdminService service;
    @Resource
    private IBackAuthGroupService groupService;
    @Resource
    private IBackAuthRuleService ruleService;
    @Resource
    private IBackAuthGroupRuleService groupRuleService;

    @Autowired
    private JwtConfigProperties jwtConfigProperties;

    /**
     * 后台管理员登录
     * @param data 传回来的表单
     * @return json
     */
    @ResponseBody
    @ApiOperation("管理员登录")
    @PostMapping("/login")
    public JSONObject adminUserLogin(@RequestBody JSONObject data){
        JSONObject jsonObject = new JSONObject();
        JSONObject jsonTemp = new JSONObject();
        String username = String.valueOf(data.get("username"));
        String password = String.valueOf(data.get("password"));
        BackAdmin admin = new BackAdmin();
        try {
            admin = service.toLogin(username,password);
            if (admin != null){
                if (admin.getAStatus() == 1){
                    jsonObject.put("code", 200);
                    jsonObject.put("msg","登录成功！");
                    jsonTemp.put("token", JWTUtils.sign(String.valueOf(admin.getAId()),jwtConfigProperties));
                    jsonObject.put("data",jsonTemp);
                }else{
                    jsonObject.put("code", 310);
                    jsonObject.put("msg","该账号已被封禁");
                }
            }else{
                jsonObject.put("code", 510);
                jsonObject.put("msg","用户名或密码错误");
            }
        }catch (Exception e){
            e.printStackTrace();
            jsonObject.put("code", 500);
            jsonObject.put("msg","服务器异常，请求失败");
        }
        return jsonObject;
    }

    /**
     * 获取管理员信息
     * @return json
     */
    @ResponseBody
    @ApiOperation("获取管理员信息")
    @GetMapping("/getUserInfo")
    public JSONObject getUserInfo(){
        JSONObject jsonObject = new JSONObject();
        JSONObject jsonTemp = new JSONObject();
        Integer id = Integer.parseInt(Objects.requireNonNull(JWTUtils.getUserId(JwtInterceptor.getTokenInfo())));
        BackAdmin admin = new BackAdmin();
        try {
            admin = service.getById(id);
            jsonObject.put("code", 200);
            jsonObject.put("msg","登录成功！");
            jsonTemp.put("userInfo", admin);
            jsonTemp.put("username", admin.getAUsername());
            jsonTemp.put("avatar", admin.getAAvatar());
            jsonTemp.put("aid", "不告诉你");
            jsonTemp.put("roles", new String[]{"Admin"});
            jsonTemp.put("permissions", new String[]{"read:system","write:system","delete:system"});
            jsonObject.put("data",jsonTemp);
        }catch (Exception e){
            e.printStackTrace();
            jsonObject.put("code", 500);
            jsonObject.put("msg","服务器异常，请求失败");
        }
        return jsonObject;
    }

    @ApiOperation("获取菜单权限")
    @ResponseBody
    @GetMapping("/getRuleRouters")
    public JSONObject getRuleRouters(){
        JSONObject jsonObject = new JSONObject();
        JSONObject jsonTemp = new JSONObject();
        //根据token取id，进阶获取用户角色组id
        Integer aId = Integer.parseInt(Objects.requireNonNull(JWTUtils.getUserId(JwtInterceptor.getTokenInfo())));
        Integer groupId = service.getById(aId).getAGroupId();
        //根据角色id获取角色权限
        BackAuthGroup group = groupService.getById(groupId);
        try {
            List<BackAuthRule> rules = new ArrayList<>();
            if (("SUPER_ADMIN").equals(group.getRole())){
                //最高权限管理员
                rules = ruleService.getAllRules(null,group.getRole());
                jsonObject.put("code",200);
                jsonObject.put("msg","获取成功");
                jsonTemp.put("list",rules);
                jsonObject.put("data",jsonTemp);
            }else{
                //普通权限管理员
                //获取联表信息
                System.err.println(groupId);
                List<BackAuthGroupRule> groupRules = groupRuleService.getIdsByGroupId(groupId);
                System.err.println(groupRules);
                rules = ruleService.getAllRules(groupRules,group.getRole());
                jsonObject.put("code",200);
                jsonObject.put("msg","获取成功");
                jsonTemp.put("list",rules);
                jsonObject.put("data",jsonTemp);
            }
        }catch (Exception e){
            e.printStackTrace();
            jsonObject.put("code",500);
            jsonObject.put("msg","服务器异常，获取失败");
        }
        return jsonObject;
    }

    /**
     * 退出登录
     * @return json
     */
    @ApiOperation("退出登录")
    @ResponseBody
    @GetMapping("/logout")
    public JSONObject logout(){
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code",200);
        jsonObject.put("msg","请求登出成功");
        return jsonObject;
    }

    /**
     * 加载管理员列表
     * @param pageNo 页码
     * @param pageSize  每页装载量
     * @return json
     */
    @ApiOperation("获取管理员列表")
    @ResponseBody
    @GetMapping("/getList")
    public JSONObject getList(
            @RequestParam("pageNo") Integer pageNo,
            @RequestParam("pageSize") Integer pageSize,
            @RequestParam(name = "title",defaultValue = "") String title){
        JSONObject jsonObject = new JSONObject();
        JSONObject jsonTemp = new JSONObject();
        Integer aId = Integer.parseInt(Objects.requireNonNull(JWTUtils.getUserId(JwtInterceptor.getTokenInfo())));
        Integer groupId = service.getById(aId).getAGroupId();
        //根据角色id获取角色权限
        BackAuthGroup group = groupService.getById(groupId);
        try {
            if ("SUPER_ADMIN".equals(group.getRole())){
                //最高权限，必然获取
                PageInfo<BackAdmin> list = service.getList(pageNo,pageSize,title);
                jsonObject.put("code",200);
                jsonObject.put("msg","获取成功");
                jsonTemp.put("list",list.getList());
                jsonTemp.put("total",list.getTotal());
                jsonObject.put("data",jsonTemp);
            }else{
                //普通权限，必然不能拥有系统管理的权限-防止篡位
                jsonObject.put("code",310);
                jsonObject.put("msg","无权访问，您没有权限");
            }
        }catch (Exception e){
            e.printStackTrace();
            jsonObject.put("code",500);
            jsonObject.put("msg","服务器异常，获取失败");
        }
        return jsonObject;
    }

    /**
     * 重置密码为 123456
     * @param bean pojo实体类
     * @return json
     */
    @ApiOperation("重置密码")
    @PostMapping("/resetPassword")
    @ResponseBody
    public JSONObject resetPassword(@RequestBody BackAdmin bean) {
        JSONObject jsonObject = new JSONObject();
        bean.setAPassword("123456");
        service.doEdit(bean);
        jsonObject.put("code",200);
        jsonObject.put("msg","重置成功！");
        return jsonObject;
    }

    /**
     * 添加 or 编辑 管理员
     * @param bean pojo实体类
     * @return json
     */
    @ApiOperation("添加 or 编辑 管理员")
    @PostMapping("/doEdit")
    @ResponseBody
    public JSONObject doEdit(@RequestBody BackAdmin bean){
        JSONObject jsonObject = new JSONObject();
        int editNum = 0;
        try {
            boolean isLastSuperAdmin = false;
            boolean isLoginAdmin = false;
            int ret = 0;
            boolean isSuperAdmin = "SUPER_ADMIN".equals(groupService.getGroupById(service.getById(Integer.parseInt(Objects.requireNonNull(JWTUtils.getUserId(JwtInterceptor.getTokenInfo())))).getAGroupId()).getRole());
            //防止postman等应用于一般管理员入侵
            if (!isSuperAdmin){
                jsonObject.put("code",250);
                jsonObject.put("msg","操作失败，该操作需要最高权限");
                return jsonObject;
            }
            /**
             * 添加要求
             * 登录账号必须唯一
             */
            if (bean.getAId()==null){
                if (service.getByUsername(bean.getAUsername()) > 0){
                    //存在用户，驳回
                    jsonObject.put("code",530);
                    jsonObject.put("msg","账号已存在");
                    return jsonObject;
                }
            }
            /**
             * 编辑要求
             * 你不能给自己降权，你不能给仅剩一个的超管降权
             */
            if (bean.getAId()!=null){
                //如果是最后一个超管-不允许降权
                if (groupService.getSuperAdminNum() <= 1){
                    isLastSuperAdmin = true;
                }
                //如果这个人是登录账号，拒绝降权
                if (bean.getAId() == Integer.parseInt(Objects.requireNonNull(JWTUtils.getUserId(JwtInterceptor.getTokenInfo())))){
                    isLoginAdmin = true;
                }
                if (isLastSuperAdmin || isLoginAdmin){
                    //说明不能够降权，查询操作是否是降权（也可能是升权或本来就是最高权限）-目标不是超管，但本来是超管（右）
                    if (!"SUPER_ADMIN".equals(groupService.getGroupById(bean.getAGroupId()).getRole()) && "SUPER_ADMIN".equals(groupService.getGroupById(service.getById(bean.getAId()).getAGroupId()).getRole())){
                        //操作是降权，根据true驳回
                        ret = isLastSuperAdmin && isLoginAdmin ?-1: isLastSuperAdmin ?-2: -3;
                    }
                }
                //不允许的降权，return
                if (ret < 0){
                    jsonObject.put("code",520);
                    switch (ret){
                        case -1:jsonObject.put("msg","您不能为您的账号降权，且此时仅剩一个超级管理员");break;
                        case -2:jsonObject.put("msg","您不能为唯一的超级管理员降低权限");break;
                        case -3:jsonObject.put("msg","您不能为您的账号降权");break;
                        default:jsonObject.put("msg","降权失败");break;
                    }
                    return jsonObject;
                }
            }
            /*
              没有被拦截
              走添加/编辑方法
             */
            boolean isAdd = bean.getAId() == null;
            editNum += service.doEdit(bean);
            if (editNum > 0){
                jsonObject.put("code",200);
                jsonObject.put("msg",isAdd?"添加成功":"编辑成功");
            }else{
                jsonObject.put("code",510);
                jsonObject.put("msg","操作失败");
            }
        }catch (Exception e){
            e.printStackTrace();
            jsonObject.put("code",500);
            jsonObject.put("msg","服务器异常，操作失败");
        }
        return jsonObject;
    }

    /**
     * 删除管理员
     * @param data json类型的ids-需要处理成数组和list
     * @return json
     */
    @ApiOperation("删除管理员")
    @ResponseBody
    @PostMapping("/doDelete")
    public JSONObject doDelete(@RequestBody JSONObject data){
        JSONObject jsonObject = new JSONObject();
        //处理前端数据
        String[] idsStr = String.valueOf(data.get("ids")).split(",");
        List<Integer> ids = new ArrayList<>();
        for (String s : idsStr) {
            ids.add(Integer.parseInt(s));
        }
        //遍历，确认其身份不是SUPER_ADMIN，否则return
        int beforeIdsSize = ids.size();
        for (int i = 0; i < ids.size() ;i++) {
            if ("SUPER_ADMIN".equals(groupService.getGroupById(service.getById(ids.get(i)).getAGroupId()).getRole())){
                ids.remove(i --);
            }
        }
        if (ids.size() < beforeIdsSize){
            jsonObject.put("code",500);
            jsonObject.put("msg","选择中含有"+(beforeIdsSize - ids.size())+"个超级管理员，请取消相应的勾选");
            return jsonObject;
        }
        //初始化
        int delNum = 0;
        //执行
        try {
            delNum += service.doDeleteBy(ids);
            if (delNum >= ids.size()){
                jsonObject.put("code",200);
                jsonObject.put("msg","已删除"+delNum+"个管理员");
            }else if (delNum > 0){
                jsonObject.put("code",200);
                jsonObject.put("msg","部分删除成功，"+delNum+"/"+ids.size());
            }else{
                jsonObject.put("code",500);
                jsonObject.put("msg","服务器异常，删除失败");
            }
        }catch (Exception e){
            jsonObject.put("code",500);
            jsonObject.put("msg","服务器异常，操作失败");
        }
        return jsonObject;
    }

    /**
     * 禁用 or 启用 管理员
     * @param bean pojo实体类
     * @return json
     */
    @ApiOperation("禁用/启用管理员")
    @PostMapping("/changeStatus")
    @ResponseBody
    public JSONObject changeStatus(@RequestBody BackAdmin bean){
        JSONObject jsonObject = new JSONObject();
        if (service.doEdit(bean) > 0){
            jsonObject.put("code",200);
            jsonObject.put("msg",bean.getAStatus()==1?"启用成功！":"禁用成功！");
        }else{
            jsonObject.put("code",500);
            jsonObject.put("msg","处理失败！");
        }
        return jsonObject;
    }
}
